package com.itheima.controller;

import com.itheima.Service.MemberService;
import com.itheima.Service.ReportService;
import com.itheima.Service.SetmealService;
import com.itheima.common.constant.MessageConstant;
import com.itheima.common.entity.Result;

import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@RequestMapping("/report")
@Slf4j
public class ReportController {

    @Autowired
    private SetmealService setmealService;

    @Autowired
    private ReportService reportService;

    @Autowired
    private MemberService memberService;

    @GetMapping("/getMemberReport")
    public Result getMemberReport(){
        try {
            // 先获得一个日历对象
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.MONTH,-12); // 获得当前日期之前12个月的日期

            List<String> list = new ArrayList<>();
            for (int i = 0; i < 12; i++) {
                calendar.add(Calendar.MONTH,1);
                //将当前的日期格式化为“yyyy.MM”的字符串形式，并将其添加到 list 列表中
                list.add(new SimpleDateFormat("yyyy-MM").format(calendar.getTime()));
            }

            Map<String,Object> map = new HashMap<>();
            map.put("months",list);

            List<Integer> memberCount = memberService.findMemberCountByMonth(list);
            map.put("memberCount",memberCount);
            return new Result(true, MessageConstant.GET_MEMBER_NUMBER_REPORT_SUCCESS,map);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false,MessageConstant.GET_MEMBER_NUMBER_REPORT_FAIL);

        }
    }

    /**
     * 套餐占比统计
     * @return
     */
    @RequestMapping("/getSetmealReport")
    public Result getSetmealReport() {
        List<Map<String, Object>> list = setmealService.findSetmealCount();

        Map<String, Object> map = new HashMap<>();
        map.put("setmealCount", list);

        List<String> setmealNames = new ArrayList<>();
        for (Map<String, Object> m : list) {
            String name = (String) m.get("name");
            setmealNames.add(name);
        }
        map.put("setmealNames", setmealNames);

        return new Result(true, MessageConstant.GET_SETMEAL_COUNT_REPORT_SUCCESS, map);
    }

    /**
     * 获取运营统计数据
     * @return
     */
    @GetMapping("/getBusinessReportData")
    public Result getBusinessReportData(){
        log.info("获取运营统计数据");
        try {
            Map<String, Object> result = reportService.getBusinessReport();
            return new Result(true,MessageConstant.GET_BUSINESS_REPORT_SUCCESS,result);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(true,MessageConstant.GET_BUSINESS_REPORT_FAIL);
        }
    }

    /**
     * 导出运营数据
     * @param request
     * @param response
     * @return
     */
    @GetMapping("/exportBusinessReport")
    public Result exportBusinessReport(HttpServletRequest request, HttpServletResponse response) throws Exception {
        try (XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream("E:\\chuanzhi\\bxg-health-backend\\src\\main\\resources\\templates\\report_template.xlsx"))) {
            // 远程调用报表服务获取报表数据
            Map<String, Object> result = reportService.getBusinessReport();

            // 获取工作表
            XSSFSheet sheet = workbook.getSheetAt(0);

            // 写日期--->第三行第六列
            writeCell(sheet, 2, 5, result.get("reportDate"));

            // 写会员(新增会员,总会员,本周新增,本月新增)
            writeCell(sheet, 4, 5, result.get("todayNewMember"));
            writeCell(sheet, 4, 7, result.get("totalMember"));
            writeCell(sheet, 5, 5, result.get("thisWeekNewMember"));
            writeCell(sheet, 5, 7, result.get("thisMonthNewMember"));

            // 写预约(本日,本周,本月)和到诊数据(本日,本周,本月)
            writeCell(sheet, 7, 5, result.get("todayOrderNumber"));
            writeCell(sheet, 7, 7, result.get("todayVisitsNumber"));
            writeCell(sheet, 8, 5, result.get("thisWeekOrderNumber"));
            writeCell(sheet, 8, 7, result.get("thisWeekVisitsNumber"));
            writeCell(sheet, 9, 5, result.get("thisMonthOrderNumber"));
            writeCell(sheet, 9, 7, result.get("thisMonthVisitsNumber"));

            // 写入热门套餐数据
            List<Map> hotSetmeal = (List<Map>) result.get("hotSetmeal");
            int rowNum = 12;
            for (Map map : hotSetmeal) {
                writeCell(sheet, rowNum, 4, map.get("name")); // 套餐名称
                writeCell(sheet, rowNum, 5, map.get("setmeal_count")); // 预约数量
                writeCell(sheet, rowNum, 6, ((BigDecimal) map.get("proportion")).doubleValue()); // 占比
                rowNum++;
            }

            // 设置响应头信息
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("report_template.xlsx", "UTF-8"));

            // 导出Excel文件
            try (OutputStream out = response.getOutputStream()) {
                workbook.write(out);
            }

            return null;

        } catch (Exception e) {
            e.printStackTrace(); // 在生产环境中应该使用日志记录错误
            return new Result(false, MessageConstant.GET_BUSINESS_REPORT_FAIL, null);
        }
    }

    private void writeCell(Sheet sheet, int rowIndex, int cellIndex, Object value) {
        //行是否为 null。如果为 null，则调用 createRow(rowIndex) 方法创建一个新的行，并将其赋值给 row
        Row row = sheet.getRow(rowIndex);
        if (row == null) {
            row = sheet.createRow(rowIndex);
        }
        //检查 cell 是否为 null。如果是，调用 createCell(cellIndex) 方法创建一个新的单元格，并将其赋值给 cell
        Cell cell = row.getCell(cellIndex);
        if (cell == null) {
            cell = row.createCell(cellIndex);
        }

        //value 是否是 String 类型
        if (value instanceof String) {
            //这一行将 value 转换为 String 类型，并将该字符串设置为 Excel 单元格的值
            cell.setCellValue((String) value);
        } else if (value instanceof Integer) {
            cell.setCellValue((Integer) value);
        } else if (value instanceof Long) {
            cell.setCellValue((Long) value);
        } else if (value instanceof Double) {
            cell.setCellValue((Double) value);
        } else if (value instanceof BigDecimal) {
            cell.setCellValue(((BigDecimal) value).doubleValue());
        } else if (value != null) {
            cell.setCellValue(value.toString());
        }
    }
}

